using System;
using System.Globalization;
using GammaJul.ReSharper.GammaXaml.Highlightings.Xaml;
using JetBrains.Annotations;
using JetBrains.ProjectModel;
using JetBrains.ReSharper.Daemon;
using JetBrains.ReSharper.Psi;
using JetBrains.ReSharper.Psi.Xaml.Impl.Tree;

[assembly: RegisterConfigurableSeverity(
	MeaninglessAttachedSetterForChildrenHighlighting.SeverityId,
	null,
	HighlightingGroupIds.CodeRedundancy,
	MeaninglessAttachedSetterForChildrenHighlighting.Description,
	MeaninglessAttachedSetterForChildrenHighlighting.Description,
	Severity.SUGGESTION,
	false)]

namespace GammaJul.ReSharper.GammaXaml.Highlightings.Xaml {

	/// <summary>
	/// An highlighting that indicates that an attached setter has no meaning unless it's on the child of a specific parent type.
	/// </summary>
	[ConfigurableSeverityHighlighting(SeverityId, XamlProjectFileType.Name, AttributeId = HighlightingAttributeIds.DEADCODE_ATTRIBUTE, OverlapResolve = OverlapResolveKind.DEADCODE)]
	public class MeaninglessAttachedSetterForChildrenHighlighting : MeaninglessAttachedSetterHighlightingBase {
		internal const string SeverityId = "Xaml.MeaninglessAttachedSetterForChildren";
		internal const string Description = "An attached property setter only have a meaning on the children of <Element>.";

		private readonly ITypeElement _expectedContainingType;
		private readonly bool _isForDescendants;

		[NotNull]
		public ITypeElement ExpectedContainingType {
			get { return _expectedContainingType; }
		}

		public bool IsForDescendants {
			get { return _isForDescendants; }
		}

		protected override string GetToolTipEnd() {
			string appliedOn = _isForDescendants ? "descendants" : "children";
			return String.Format(CultureInfo.CurrentCulture, "{0} of '{1}'", appliedOn, _expectedContainingType.ShortName);
		}

		public override bool IsValid() {
			return base.IsValid() && _expectedContainingType.IsValid();
		}

		public MeaninglessAttachedSetterForChildrenHighlighting([NotNull] IPropertySetter propertySetter, [NotNull] IMethod attachedSetter, [NotNull] ITypeElement expectedContainingType, bool isForDescendants)
			: base(propertySetter, attachedSetter) {
			if (expectedContainingType == null)
				throw new ArgumentNullException("expectedContainingType");

			_expectedContainingType = expectedContainingType;
			_isForDescendants = isForDescendants;
		}
	}

}
